﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using SpriteSheetRuntime;

namespace Megaman
{
    class AnimatedStateManager<StateName>
    {

        private struct StateData
        {
            public float TIME;
            public float elapsedTimer;
            public bool stateStarted;
            public bool stateFinished;
            public bool soundPlayed;
            public Animation animation;
            public SoundEffect effect;

            public StateData(float time, Animation anime, SoundEffect effect)
            {
                TIME = time;
                elapsedTimer = 0f;
                stateStarted = false;
                stateFinished = false;
                soundPlayed = false;
                this.animation = anime;
                this.effect = effect;
            }
        }    

        private Dictionary<StateName,StateData> States = new Dictionary<StateName,StateData>();

        public void Add(StateName name,float time, Animation animation, SoundEffect effect)
        {
            States.Add(name,new StateData(time,animation,effect));
        }

        public bool hasStarted(StateName name)
        {
            return States[name].stateStarted;
        }

        public bool hasFinished(StateName name)
        {
            return States[name].stateFinished;
        }

        public bool stillPlaying(StateName name)
        {
            return States[name].stateStarted && !States[name].stateFinished;
        }

        public Animation getAnimation(StateName name)
        {
            return States[name].animation;
        }

        public SoundEffect getSoundEffect(StateName name)
        {
            return States[name].effect;
        }

        public float getElapsedTime(StateName name)
        {
            return States[name].elapsedTimer;
        }
        public bool updateTimer(StateName name, float elapsed)
        {
            StateData data;
            data = States[name];
            if (!data.stateStarted)
                data.stateStarted = true;

            if (data.stateFinished)
                return false;
            data.elapsedTimer += elapsed;
            if (data.elapsedTimer >= States[name].TIME)
            {
                data.stateFinished = true;
                States[name] = data;
                return false;
            }
            States[name] = data;
            return true;
        }

        public void resetState(StateName name)
        {
            StateData data = States[name];
            data.stateFinished = data.stateStarted = data.soundPlayed = false;
            data.elapsedTimer = 0f;
            data.soundPlayed = false;
            States[name] = data;
        }

        public void startState(StateName name)
        {
            StateData data = States[name];
            data.stateStarted = true;
            States[name] = data;
        }

        public void playSound(StateName name)
        {
            StateData data = States[name];
            data.soundPlayed = true;
            data.effect.Play();
            States[name] = data;
        }

        public bool hasTheSoundPlayed(StateName name)
        {
            return States[name].soundPlayed;
        }

        public float getTime(StateName name)
        {
            return States[name].TIME;
        }
    }
}
